package com.hsc.box;

/**
 * 思考的问题:
 * 前面我们已经对ArrayBox和LinkedBox完成了封装 如果我们站着一个用户的角度去思考问题 提供两个工具类，他们的方法名称以及用法都是一样的,
 * 能不能抽象一层出来，作为一个标准对外进行提供使用？或者以后用户看到了Box的类，就可以直接知道这个类所提供的功能，比如添加元素、删除元素、查询元素这几个主要的方法。用户根据自己的需要使用不同的容器（比如:是要追求查询快，还是说追求删除、添加元素速度快）
 * 再比如后续我们有着更多的关于Box提供的方法是一样的，但是底层的使用存储的数据结构是不一样的，他们针对使用的场景也是不一样的。
 * 我们就引出接口的一个概念，对Box使用标准做一个规范，直接定义标准。这样既可以用户使用起来方便，后续如果有着更好的处理方法来满足容器的增删查的功能，也可以直接进行扩展
 */
public interface Box<T> {
    /**
     * 【主要的方法】：规定一个标准，添加的一个元素的方法，如果子类或实现也属于Box的这个体系，就必须有添加元素的这个能力
     * public abstract 权限修饰符和特征修饰符接口默认携带的，可以写也可以不写
     *
     * @param element
     * @return
     */
    public abstract boolean add(T element);

    /**
     * 【主要方法】：接口中定义了一个标准，查询的方法：根据索引的下标，获取到对应的元素
     *
     * @param index
     * @return
     */
    public abstract T get(int index);


    /**
     * 【主要方法】：接口中定义了一个标准，删除一个元素的方法：根据索引的下标，删除对应元素。如果子类或实现也属于Box的这个体系，就必须有添加元素的这个能力
     *
     * @param index
     * @return
     */
    public abstract T remove(int index);


    /**
     * 【非主要方法】：指定位置，添加指定元素的方法，如果这个方法不是整个Box体系中必须提供的能力，我们可以不一定在接口中强制规定，因为接口中规定了，实现类进行实现了，就必须实现该方法
     *
     * @param index
     * @param element
     * @return
     */
    public abstract boolean add(int index, T element);

    /**
     * 【非主要方法】添加整个容器的方法：我们还可以定义一个添加所有元素的方法。但是这个方法也不是子类中必须要实现，或者说是后续规范要做的功能，我们可以不一定在接口中强制规定，我们放在抽象类，中间层中实现
     * @param box
     *
     */
//    public abstract void  addAll(Box<T> box);

    /**
     * 【非主要方法】在指定的位置，添加所有元素的方法，个方法也不是子类中必须要实现，或者说是后续规划要实现的功能,我们可以不一定在接口中强制规定,我们放在抽象类，中间层中实现
     * @param index
     * @param box
     * @return
     */
//    public abstract void  addAll(int index,Box<T> box);
}
